package App.Filter;

//import App.Config.JwtConfig;
import App.Repository.AccountRepository;
import App.Utility.JwtAuth;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.security.SecurityProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.access.AccessDeniedHandler;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.authentication.www.BasicAuthenticationEntryPoint;

import javax.servlet.http.HttpServletResponse;
import java.util.logging.Logger;


@Configuration
@EnableWebSecurity
//@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
//@Order(SecurityProperties.BASIC_AUTH_ORDER)
public class MyWebSecurityConfig extends WebSecurityConfigurerAdapter {

    Logger _log = Logger.getLogger("MyWebSecurityConfig");


    @Autowired
    private UserDetailsService userDetailsService;

    @Autowired
    private JwtAuth _jwtAuth;


    @Autowired
    private AccountRepository _accountRepository;

    // private UserDetailsService userDetailsService;
    //private BCryptPasswordEncoder bCryptPasswordEncoder;
/*
    public MyWebSecurityConfig(UserDetailsService userDetailsService, BCryptPasswordEncoder bCryptPasswordEncoder) {
        this.userDetailsService = userDetailsService;
        this.bCryptPasswordEncoder = bCryptPasswordEncoder;
    }*/

/*
    @Override
    public void configure(HttpSecurity http) throws Exception
    {
        http.addFilterBefore(corsFilter(), ChannelProcessingFilter.class).logout().deleteCookies("JESSIONID")
                .logoutUrl("/api/logout").logoutSuccessHandler(logoutSuccessHandler()).and().formLogin().loginPage("/login")
                .loginProcessingUrl("/api/login")
                .failureHandler(authenticationFailureHandler())
                .successHandler(authenticationSuccessHandler())
                .and().csrf().disable()
                .exceptionHandling()
                .authenticationEntryPoint(authenticationEntryPoint())
                .accessDeniedHandler(accessDeniedHandler());
    }*/

    @Override
    public void configure(WebSecurity web){
        //web.ignoring().antMatchers(HttpMethod.GET, "/apple-app-site-association");
        web.ignoring().antMatchers( 
                "/apple-app-site-association"
        );
    }
    @Override
    protected void configure(HttpSecurity http) throws Exception {


        http.cors().and().csrf().disable().authorizeRequests()
                .antMatchers(HttpMethod.POST, "/api/account/login").permitAll()
                .antMatchers(HttpMethod.POST, "/api/account/key/login").permitAll()
                .antMatchers(HttpMethod.POST, "/api/account/register").permitAll()
                .antMatchers(HttpMethod.POST, "/api/account/getcode").permitAll()
                .antMatchers(HttpMethod.POST, "/api/account/checkcode").permitAll()
                .antMatchers(HttpMethod.POST, "/api/account/checkphone").permitAll()
                .antMatchers(HttpMethod.POST, "/api/account/changepwd").permitAll()
                .antMatchers(HttpMethod.POST, "/api/account/getqrcode").permitAll()
                .antMatchers(HttpMethod.POST, "/api/account/gettoken").permitAll()
                .antMatchers(HttpMethod.POST, "/api/account/pushweblogin").permitAll()
                .antMatchers(HttpMethod.POST, "/api/account/isconfirmed").permitAll()
                .antMatchers(HttpMethod.POST, "/api/account/get/token").permitAll()
                .antMatchers(HttpMethod.POST, "/api/account/shoptoken").permitAll()
                .antMatchers(HttpMethod.POST, "/api/account/tokenbytoken").permitAll()
                .antMatchers(HttpMethod.POST, "/api/account/checktoken").permitAll()
                .antMatchers(HttpMethod.GET, "/api/file/download").permitAll()
                .antMatchers(HttpMethod.GET, "/file/**").permitAll()
                .antMatchers(HttpMethod.GET, "/test/**").permitAll()
                .antMatchers("/swagger-ui.html").permitAll()
                .antMatchers("/webjars/**").permitAll()
                .antMatchers("/swagger-resources/**").permitAll()
                .antMatchers("/v2/**").permitAll()
                .antMatchers("/csrf").permitAll()
                .antMatchers(HttpMethod.POST, "/api/demo/*").permitAll()
                .antMatchers(HttpMethod.POST, "/api/account/checkcodelogin").permitAll()
                .antMatchers(HttpMethod.POST, "/api/account/getmobilenewtoken").permitAll()
                .antMatchers(HttpMethod.POST, "/api/chat/imcallback").permitAll()
//                .antMatchers(HttpMethod.POST, "/api/*/*").permitAll()
                .anyRequest().authenticated()
                .and()
                .addFilter(new JWTLoginFilter(authenticationManager()))
                .addFilter(new JwtAuthenticationFilter(authenticationManager(),_jwtAuth,_accountRepository))
                //.addFilter(new StubLoggingFilter())
                .exceptionHandling()
                //.accessDeniedHandler(accessDeniedHandler())
                .authenticationEntryPoint(authenticationEntryPoint()).and().headers().frameOptions().disable();
        // ;


/*
        http
                .csrf().disable()
                // make sure we use stateless session; session won't be used to store user's state.
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                // handle an authorized attempts
                .exceptionHandling().authenticationEntryPoint((req, rsp, e) -> rsp.sendError(HttpServletResponse.SC_UNAUTHORIZED))
                .and()
                // Add a filter to validate the tokens with every request
                .addFilterAfter(new JwtAuthenticationFilter(jwtConfig), UsernamePasswordAuthenticationFilter.class)
                // authorization requests config
                .authorizeRequests()
                // allow all who are accessing "auth" service
                .antMatchers(HttpMethod.POST, jwtConfig.getUri()).permitAll()
                // must be an admin if trying to access admin area (authentication is also required here)
                .antMatchers("/gallery" + "/admin/**").hasRole("ADMIN")
                // Any other request must be authenticated
                .anyRequest().authenticated();

                */
    }

    @Override
    public void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
    }

    @Bean
    public BCryptPasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }


    /*
    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
                .withUser("user")
                .password("password")
                .roles("USER");
    }*/

    @Bean
    public AuthenticationFailureHandler authenticationFailureHandler() {
        return new RestAuthenticationFailureHandler();
    }

    /**
     * @return Custom {@link AuthenticationSuccessHandler} to send suitable response to REST clients in the event of a
     * successful authentication attempt.
     */
    /*
    @Bean
    public AuthenticationSuccessHandler authenticationSuccessHandler()
    {
        return new  App.Filter.RestAuthenticationSuccessHandler();
    }
 */
    @Bean
    public AccessDeniedHandler accessDeniedHandler() {
        return new RestAccessDeniedHandler();
    }

    @Bean
    public AuthenticationEntryPoint authenticationEntryPoint() {

        _log.info("access deny error:luke26");

       /* BasicAuthenticationEntryPoint entryPoint = new BasicAuthenticationEntryPoint();
        entryPoint.setRealmName("admin realm");
        return entryPoint;
*/

        return new CustomAuthenticationEntryPoint();
    }

/*
    @Bean
    public JwtConfig jwtConfig() {
        return new JwtConfig();
    }
*/
}
